#ifndef TC_MACD_HPP
#define TC_MACD_HPP

/** \file MACD.hpp
 * Definitions of the MACD function templates.
 *
 * (C) Copyright 2003-2006 by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: MACD.hpp 110 2006-06-19 03:38:33Z semihc $
 *
 *
 */

#include <vector>
#include "TA.hh"
#include "DBC.hpp"
#include "MAExpon.hpp"



namespace TC {

  //! Moving Average Convergence-Divergence
  //! Based on periods.
  TC_EXPORT template <typename InputIterator,
                      typename OutputIterator,
                      class Adaptor>
  void MACD(InputIterator fromPos,
            InputIterator fromEnd,
            OutputIterator toPos,
            const unsigned prdFast, 
            const unsigned prdSlow,
            const Adaptor adaptor)
  {
    TC_PRE_CONDITION(prdFast > 0);
    TC_PRE_CONDITION(prdFast < prdSlow);
    
    std::vector<TAfp_t> tmpFast, tmpSlow; 

    MAExpon(fromPos, fromEnd, back_inserter(tmpFast), 
            prdFast, adaptor);
    MAExpon(fromPos, fromEnd, back_inserter(tmpSlow), 
            prdSlow, adaptor);

    TC_ASSERT(!tmpFast.empty());
    TC_ASSERT(tmpFast.size() == tmpSlow.size());

    // Get the difference between the Exp.MAs
    for(unsigned i=0; i<tmpFast.size(); ++i) {
      *toPos =  tmpFast[i] - tmpSlow[i];
      ++toPos;
    }
  }



  //! Moving Average Convergence-Divergence
  //! Based on percentage.
  TC_EXPORT template <typename InputIterator,
                      typename OutputIterator,
                      class Adaptor>
  void MACDPct(InputIterator fromPos,
               InputIterator fromEnd,
               OutputIterator toPos,
               const TAfp_t pctHigh, 
               const TAfp_t pctLow,
               const Adaptor adaptor)
  {
    TC_PRE_CONDITION(pctLow > 0.0);
    TC_PRE_CONDITION(pctHigh > pctLow);

    const int TmpColReserve = 512;
    typedef std::vector<TAfp_t> TmpCol_t;
    TmpCol_t tmpHigh, tmpLow; 
    //TODO: Decide if reserve() is necessary
    tmpHigh.reserve(TmpColReserve);
    tmpLow.reserve(TmpColReserve);

    MAExponPct(fromPos, fromEnd, back_inserter(tmpHigh), 
               pctHigh, adaptor);
    MAExponPct(fromPos, fromEnd, back_inserter(tmpLow), 
               pctLow, adaptor);
    
    TC_ASSERT(!tmpHigh.empty());
    TC_ASSERT(tmpHigh.size() == tmpLow.size());

    for(unsigned i=0; i<tmpHigh.size(); ++i) {
      *toPos =  tmpHigh[i] - tmpLow[i];
      ++toPos;
    }
  }



} // end namespace


#endif /* Include guard */
